package edu.hit.pact.pgse.master.util;

import java.util.ArrayList;
import java.util.List;
import java.util.SortedMap;
import java.util.concurrent.ConcurrentSkipListMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class DistributedMap<K, T> {
	private Log logger;
	private SortedMap<K, T> runningMap;
	
	public int getPiecesNumber(){//为测试用
		return runningMap.size();
	}
	
	public DistributedMap() {
		this(LogFactory.getLog(DistributedMap.class));
	}
	
	public DistributedMap(Log logger) {
		this.logger = logger;
		this.runningMap = new ConcurrentSkipListMap<K, T>();
	}
	
	public void add(K taskPieceId, T node) {
		logger.info("Put running info into runningMap : taskPieceId is " + taskPieceId);
		this.runningMap.put(taskPieceId, node);
	}
	
	public void remove(K taskPieceId) {
		logger.info("Remove running info from runningMap : taskPieceId is " + taskPieceId);
		this.runningMap.remove(taskPieceId);
	}
	
	public T get(K taskPieceId) {
		logger.info("Get running info from runningMap : taskPieceId is " + taskPieceId);
		return this.runningMap.get(taskPieceId);
	}
	
//	public List<SocketAddress> getByIdPrefix(String idPrefix) {
//		logger.info("Get running info from runningMap : idPrefix is " + idPrefix);
//		List<SocketAddress> nodes = new ArrayList<SocketAddress>();
//		SortedMap<K, SocketAddress> subMap = runningMap.subMap(idPrefix, idPrefix + ('-' + 1));
//		for (String taskPieceId : subMap.keySet()) {
//			nodes.add(subMap.get(taskPieceId));
//		}//end for
//		return nodes.isEmpty() ? null : nodes;
//	}
	public List<T> getValues(List<K> ids){
		if (ids == null)
			return null;
		List<T> values = new ArrayList<T>();
		for (K k:ids){
			values.add(runningMap.get(k));
		}
		return values;
	}
	/**
	 * 
	 * @param node
	 * @return retrieve all ids from running map by given node.
	 */
	public List<K> getId(T node) {
		List<K> ids = new ArrayList<K>();
		
		for (K id : runningMap.keySet()) {
			T runningNode = runningMap.get(id);
			if (node.equals(runningNode)) {
				ids.add(id);
			}//end if
		}//end for
		
		return ids.isEmpty() ? null : ids;
	}
	
	/**
	 * 
	 * @param node
	 * @return retrieve all ids from running map by given node.
	 */
	public List<K> getIdRemoveElement(T node) {
		List<K> ids = new ArrayList<K>();
		
		for (K id : runningMap.keySet()) {
			T runningNode = runningMap.remove(id);
			if (node.equals(runningNode)) {
				ids.add(id);
			}//end if
		}//end for
		
		return ids.isEmpty() ? null : ids;
	}
}
